import logging
from typing import List

from fastapi import APIRouter, Depends, HTTPException

from app.admin.schemas.resource import ResourceCreate, ResourceUpdate, ResourceResponse
from app.admin.schemas.role import Role
from app.admin.schemas.user import User
from app.admin.services.resource_service import resource_service
from app.schemas.token import APIResponse
from app.security.auth import get_current_active_superuser, PermissionRequired

# 配置日志
logger = logging.getLogger(__name__)

router = APIRouter()


@router.post("", response_model=APIResponse[ResourceResponse])
async def create_resource(
        resource: ResourceCreate,
        tenant_id: str,
        current_user: User = Depends(get_current_active_superuser)
):
    """
    创建新资源（仅限超级用户）
    """
    logger.debug(f"尝试创建资源，参数：{resource}")
    
    if resource.name is None:
        raise HTTPException(
            status_code=400,
            detail=APIResponse(code=400, msg=f"资源名称不能为空。", data=None),
        )
    
    if resource.code is None:
        raise HTTPException(
            status_code=400,
            detail=APIResponse(code=400, msg=f"资源代码不能为空。", data=None),
        )
    
    # 检查资源名称是否已存在
    existing_resource = await resource_service.get_resource_by_name(resource.name)
    if existing_resource:
        raise HTTPException(
            status_code=400,
            detail=APIResponse(code=400, msg=f"资源名称 [{resource.name}] 已存在", data=None),
        )
    
    # 检查资源代码是否已存在
    existing_resource = await resource_service.get_resource_by_code(resource.code)
    if existing_resource:
        raise HTTPException(
            status_code=400,
            detail=APIResponse(code=400, msg=f"资源代码 [{resource.code}] 已存在", data=None),
        )
    resource.tenant_id = tenant_id
    created_resource = await resource_service.create_resource(resource=resource)
    logger.info(f"创建资源成功。{created_resource}")
    return APIResponse(
        code=200,
        msg="资源创建成功",
        data=created_resource
    )


@router.get("", response_model=APIResponse[List[ResourceResponse]])
async def read_resources(
        skip: int = 0,
        limit: int = 100,
        current_user: User = Depends(PermissionRequired("resource_list"))
):
    """
    获取资源列表（需要资源访问权限）
    """
    logger.debug(f"获取资源列表，参数：skip={skip}, limit={limit}")
    resources = await resource_service.get_resources(skip=skip, limit=limit)
    logger.info(f"获取资源列表成功，共 {len(resources)} 条记录")
    return APIResponse(
        code=200,
        msg="获取资源列表成功",
        data=resources
    )


@router.get("/{resource_id}", response_model=APIResponse[ResourceResponse])
async def read_resource(
        resource_id: str,
        current_user: User = Depends(PermissionRequired("resource_detail"))
):
    """
    根据ID获取资源信息（需要资源访问权限）
    """
    logger.debug(f"获取资源信息，resource_id={resource_id}")
    db_resource = await resource_service.get_resource(resource_id=resource_id)
    if db_resource is None:
        logger.warning(f"资源不存在，resource_id={resource_id}")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"资源 [{resource_id}] 不存在", data=None)
        )
    logger.info(f"获取资源信息成功，resource_id={resource_id}")
    return APIResponse(
        code=200,
        msg="获取资源信息成功",
        data=db_resource
    )


@router.put("/{resource_id}", response_model=APIResponse[ResourceResponse])
async def update_resource(
        resource_id: str,
        resource_update: ResourceUpdate,
        current_user: User = Depends(get_current_active_superuser)
):
    """
    更新资源信息（仅限超级用户）
    """
    logger.debug(f"尝试更新资源，resource_id={resource_id}, 参数：{resource_update}")
    
    # 检查资源是否存在
    db_resource = await resource_service.get_resource(resource_id=resource_id)
    if db_resource is None:
        logger.warning(f"更新资源失败：资源不存在，resource_id={resource_id}")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"资源 [{resource_id}] 不存在", data=None)
        )
    
    # 如果更新了名称，检查名称是否已存在
    if resource_update.name and resource_update.name != db_resource.name:
        existing_resource = await resource_service.get_resource_by_name(resource_update.name)
        if existing_resource and existing_resource.id != resource_id:
            logger.warning(f"更新资源失败：资源名称已存在，name={resource_update.name}")
            raise HTTPException(
                status_code=400,
                detail=APIResponse(code=400, msg=f"资源名称 [{resource_update.name}] 已存在", data=None)
            )
    
    # 如果更新了代码，检查代码是否已存在
    if resource_update.code and resource_update.code != db_resource.code:
        existing_resource = await resource_service.get_resource_by_code(resource_update.code)
        if existing_resource and existing_resource.id != resource_id:
            logger.warning(f"更新资源失败：资源代码已存在，code={resource_update.code}")
            raise HTTPException(
                status_code=400,
                detail=APIResponse(code=400, msg=f"资源代码 [{resource_update.code}] 已存在", data=None)
            )
    
    updated_resource = await resource_service.update_resource(resource_id=resource_id, resource_update=resource_update)
    logger.info(f"资源更新成功，resource_id={resource_id}")
    return APIResponse(
        code=200,
        msg="资源信息更新成功",
        data=updated_resource
    )


@router.delete("/{resource_id}", response_model=APIResponse[bool])
async def delete_resource(
        resource_id: str,
        current_user: User = Depends(get_current_active_superuser)
):
    """
    删除资源（仅限超级用户）
    """
    logger.debug(f"尝试删除资源，resource_id={resource_id}")
    
    # 检查资源是否存在
    db_resource = await resource_service.get_resource(resource_id=resource_id)
    if db_resource is None:
        logger.warning(f"删除资源失败：资源不存在，resource_id={resource_id}")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"资源 [{resource_id}] 不存在", data=None)
        )

    # 检查资源是否被角色引用
    roles = await resource_service.get_resource_roles(resource_id=resource_id)
    if roles and len(roles) > 0:
        role_names = ", ".join([role.name for role in roles])
        logger.warning(f"删除资源失败：资源被角色引用，resource_id={resource_id}, roles={role_names}")
        raise HTTPException(
            status_code=400,
            detail=APIResponse(code=400, msg=f"资源被以下角色引用，无法删除: {role_names}", data=None)
        )

    success = await resource_service.delete_resource(resource_id=resource_id)
    logger.info(f"资源删除成功，resource_id={resource_id}")
    return APIResponse(
        code=200,
        msg="资源删除成功",
        data=success
    )


@router.get("/{resource_id}/roles", response_model=APIResponse[List[Role]])
async def get_resource_roles(
        resource_id: str,
        current_user: User = Depends(PermissionRequired("resource_roles"))
):
    """
    获取资源关联的角色列表（需要资源访问权限）
    """
    logger.debug(f"获取资源关联的角色列表，resource_id={resource_id}")
    
    # 检查资源是否存在
    db_resource = await resource_service.get_resource(resource_id=resource_id)
    if db_resource is None:
        logger.warning(f"获取资源角色失败：资源不存在，resource_id={resource_id}")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"资源 [{resource_id}] 不存在", data=None)
        )
        
    roles = await resource_service.get_resource_roles(resource_id=resource_id)
    logger.info(f"获取资源角色列表成功，resource_id={resource_id}, 角色数量={len(roles)}")
    return APIResponse(
        code=200,
        msg="获取资源角色列表成功",
        data=roles
    )